package com.et.machine.manager.vm.test

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.text.Html
import android.text.Spanned
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.Navigation
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.et.drive.out.IOutGoodsImpl
import com.et.drive.run.Run
import com.et.machine.R
import com.et.machine.convert.OutGoodsStatusEnum
import com.et.machine.convert.machineInfo
import com.et.machine.convert.size
import com.et.machine.databinding.FragmentChannelTestBinding
import com.et.machine.databinding.ItemAllBoxBinding
import com.et.machine.databinding.ItemChannelTestButtonBinding
import com.et.machine.databinding.ItemMsgListBinding
import com.et.machine.util.Adapter
import com.et.protocol.ano.GuideCode
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*

@Suppress("DEPRECATION")
class ChannelTestFragment : Fragment() {

    private val viewModel: ChannelTestViewModel by lazy {
        ViewModelProvider(this).get(ChannelTestViewModel::class.java)
    }

    private lateinit var binding: FragmentChannelTestBinding

    private lateinit var adapterChannel: TestOutAdapter<ItemChannelTestButtonBinding>
    private lateinit var adapterBox: Adapter<Box, ItemAllBoxBinding>
    private var boxData = mutableListOf<Box>()
    private var selectedBox: Box? = null
    private var autoOutFlag: Boolean = false
    private var autoOutChannelIndex: Int = 1

    private lateinit var adapterLog: Adapter<Spanned, ItemMsgListBinding>
    private var msgList: MutableList<Spanned> = mutableListOf()


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View = FragmentChannelTestBinding.inflate(inflater, container, false).apply {
        binding = this
    }.root


    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        initClickEvent()
        initBar()
        initBoxAdapter()
        initChannelAdapter()
        initLogAdapter()

    }


    private fun initClickEvent() {
        // outAllGoods
        binding.all.setOnClickListener {
            autoOutFlag = true
            autoOutChannelIndex = 1
            val outMsg = viewModel.outGoods(selectedBox?.box ?: 11, autoOutChannelIndex)
            addLogList(
                LogParam(
                    if (outMsg == OutGoodsStatusEnum.SUCCESS) LEVEL_DEBUG else LEVEL_ERROR,
                    "${viewModel.box2Name(selectedBox?.box ?: 11)}：" + "货道 $autoOutChannelIndex：" + if (outMsg == OutGoodsStatusEnum.SUCCESS) "出货中..." else "出货失败！$outMsg"
                )
            )
        }

        // cancelOutGoods
        binding.cancel.setOnClickListener {
            Run.getGuide()?.guide(GuideCode.GUI_53)
            autoOutFlag = false
        }
    }


    @SuppressLint("SetTextI18n")
    private fun initBar() {
        // back
        binding.layoutTitle.back.setOnClickListener {
            Navigation.findNavController(it).popBackStack()
        }

        binding.layoutTitle.uuid.text =
            "机器编号：${machineInfo?.uuid}"

        binding.layoutTitle.title.setText(R.string.label_title_name_channel_test)
    }

    private fun initBoxAdapter() {
        boxData = viewModel.addBoxList()
        boxData[0].apply {
            select = true
            selectedBox = this
        }
        // layout box
        binding.boxListview.also {
            it.adapter = Adapter(
                { view, _, data ->
                    view.box.text = viewModel.box2Name(data.box)
                    if (data.select) {
                        view.box.setBackgroundResource(R.drawable.radio_button_checked_icon)
                        adapterChannel.notifyData(viewModel.notifyChannelInfo(data.box))
                    } else {
                        view.box.setBackgroundResource(R.drawable.radio_button_dischecked_icon)
                    }

                    view.box.setOnClickListener {
                        if (selectedBox != null) {
                            selectedBox!!.select = false
                            data.select = true
                        }
                        selectedBox = data
                        adapterBox.notifyDataSetChanged()
                        adapterChannel.notifyData(viewModel.notifyChannelInfo(data.box))
                    }

                }, { inflater, viewGroup ->
                    ItemAllBoxBinding.inflate(inflater, viewGroup, false)
                }, boxData
            ).apply {
                adapterBox = this
            }
            it.layoutManager = LinearLayoutManager(requireContext()).apply {
                orientation = LinearLayoutManager.HORIZONTAL
            }
        }
    }

    private fun initChannelAdapter() {
        // layout channel
        binding.recyclerview.layoutManager =
            GridLayoutManager(requireContext(), size.x / 110).apply {
                orientation = LinearLayoutManager.VERTICAL
            }
        adapterChannel = TestOutAdapter({ view, _, data ->

            view.btn.text = data.toString()

            view.btn.setOnClickListener {
                val outMsg = viewModel.outGoods(selectedBox!!.box, data)
                addLogList(
                    LogParam(
                        if (outMsg == OutGoodsStatusEnum.SUCCESS) LEVEL_DEBUG else LEVEL_ERROR,
                        "${viewModel.box2Name(selectedBox!!.box)}：" + "货道 $data：" + if (outMsg == OutGoodsStatusEnum.SUCCESS) "出货中..." else "出货失败！$outMsg"
                    )
                )
            }

        }, { inflater, viewGroup ->
            ItemChannelTestButtonBinding.inflate(inflater, viewGroup, false)
        })
        binding.recyclerview.adapter = adapterChannel
    }

    private fun initLogAdapter() {
        adapterLog = Adapter({ view, _, msg ->
            view.logMsg.text = msg
        }, { inflater, parent ->
            ItemMsgListBinding.inflate(inflater, parent, false)
        }, msgList)
        binding.logRecycler.also {
            it.adapter = adapterLog
            it.layoutManager = LinearLayoutManager(requireContext()).apply {
                orientation = LinearLayoutManager.VERTICAL
            }
        }
    }


    override fun onResume() {
        super.onResume()
        IOutGoodsImpl.subscribe {
            addLogList(
                LogParam(
                    LEVEL_DEBUG,
                    "${viewModel.box2Name(it.device)}：" + "货道 ${it.channel}：" + "出货成功！"
                )
            )
            if (autoOutFlag && autoOutChannelIndex < adapterChannel.enabledCount) {
                autoOutChannelIndex++
                val outMsg = viewModel.outGoods(selectedBox?.box ?: 11, autoOutChannelIndex)
                addLogList(
                    LogParam(
                        if (outMsg == OutGoodsStatusEnum.SUCCESS) LEVEL_DEBUG else LEVEL_ERROR,
                        "${viewModel.box2Name(selectedBox?.box ?: 11)}：" + "货道 $autoOutChannelIndex：" + if (outMsg == OutGoodsStatusEnum.SUCCESS) "出货中..." else "出货失败！$outMsg"
                    )
                )
            } else {
                autoOutFlag = false
                autoOutChannelIndex = 1
            }
        }
    }


    private fun addLogList(logParam: LogParam) {
        CoroutineScope(Dispatchers.Main).launch {
            val textColor = (
                    when (logParam.level) {
                        LEVEL_DEBUG -> {
                            COLOR_DEBUG
                        }
                        LEVEL_WARN -> {
                            COLOR_WARN
                        }
                        LEVEL_ERROR -> {
                            COLOR_ERROR
                        }
                        else -> {
                            COLOR_DEBUG
                        }
                    }
                    )
            if (msgList.size > 100) msgList.clear()
            val date = SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.getDefault()).format(
                Date(System.currentTimeMillis())
            )
            msgList.add(Html.fromHtml("<font color=\"$textColor\">$date: ${logParam.msg}</font>"))
            adapterLog.notifyDataSetChanged()

            binding.logRecycler.scrollToPosition(msgList.size - 1)
        }
    }

    companion object {

        const val LEVEL_DEBUG = 0
        const val LEVEL_WARN = 1
        const val LEVEL_ERROR = 2
        const val COLOR_DEBUG = Color.BLACK
        const val COLOR_WARN = Color.BLUE
        const val COLOR_ERROR = Color.RED

        data class LogParam(var level: Int = LEVEL_DEBUG, val msg: String)


        data class Box(var select: Boolean, val box: Int)

        const val BOX_11 = 11
        const val BOX_09 = 9
        const val BOX_08 = 8
        const val BOX_07 = 7
        const val BOX_06 = 6
        const val BOX_01 = 1
        const val BOX_02 = 2
        const val BOX_03 = 3
        const val BOX_04 = 4
        const val BOX_05 = 5
    }

}
